<script lang="ts" setup>
import type { FormInstance } from "element-plus";

// 使用索引签名定义对象类型
type GenericObject = {
  [key: string]: any;
};

const props = defineProps<{
  Model?: GenericObject;
  disabled?: boolean;
  hideHandle?: boolean;
  saveAPI?: string;
  saveOK?: () => void;
  local_save?: (formData: GenericObject) => void;
  cancel?: () => void;
  colNum?: number;
  action?: string;
  PageConfig?: GenericObject;
}>();

const formData = defineModel<GenericObject>({});

const formItemConfigList = computed(() => {
  let result: any = [];
  if (props.Model) {
    for (const [key, value] of Object.entries(props.Model)) {
      let temp_value = JSON.parse(JSON.stringify(value));
      // 解析 -- 必填
      if ("require" in temp_value && temp_value.require) {
        if (
          "formRules" in temp_value &&
          temp_value.formRules &&
          Array.isArray(temp_value.formRules)
        ) {
          temp_value.formRules.push({
            required: true,
            message: "请输入" + temp_value.label,
          });
        } else {
          temp_value.formRules = [
            {
              required: true,
              message: "请输入" + temp_value.label,
            },
          ];
        }
      }

      result.push({
        prop: key,
        ...(temp_value as object),
      });
    }
  }
  return result;
});

const group_formItemConfigList_Obj = computed(() => {
  let result: any = {};
  if (props.PageConfig && props.PageConfig.formGrouped) {
    let final_formItemConfigList: any[] = [];
    formItemConfigList.value.forEach((formItemConfig: any) => {
      if (
        !(
          formItemConfig.formHide &&
          (formItemConfig.formHide === "all" ||
            (Array.isArray(formItemConfig.formHide) &&
              formItemConfig.formHide.includes(props.action)))
        )
      ) {
        final_formItemConfigList.push(formItemConfig);
      }
    });
    result = groupBy(
      final_formItemConfigList,
      "group",
      props.PageConfig.groupName_default
    );
  }
  return result;
});

const activeGroups: string[] = Object.keys(group_formItemConfigList_Obj.value);

const pageData = reactive<{
  localFormData: GenericObject;
}>({
  localFormData: formData.value || {},
});

const { localFormData } = toRefs(pageData);

const formRef = ref<FormInstance>();

const callbackMessage = ref({
  show: false,
  valid: true,
  content: "",
});

// 按钮 -- 保存
const submitForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.validate(async (valid) => {
    if (valid) {
      if (props.local_save) {
        props.local_save(pageData.localFormData);
        return;
      }

      try {
        await $fetch(`/api${props.saveAPI}`, {
          body: pageData.localFormData,
          method: "POST",
        });
        callbackMessage.value = {
          show: true,
          valid: true,
          content: "操作成功",
        };
        if (props.saveOK) {
          props.saveOK();
        }
      } catch (e: any) {
        callbackMessage.value = {
          show: true,
          valid: false,
          content: e.data.message,
        };
      }
    } else {
      console.log("提交报错!");
    }
  });
};

// 将方法暴露给父组件
defineExpose({
  submitForm,
  localFormData,
  formRef,
});
</script>
<template>
  <div class="relative mt-10">
    <el-scrollbar max-height="460px" class="px10">
      <el-form
        ref="formRef"
        :inline="true"
        :model="localFormData"
        :disabled="props.disabled"
      >
        <el-collapse
          v-if="props.PageConfig && props.PageConfig.formGrouped"
          v-model="activeGroups"
        >
          <el-collapse-item
            :name="group"
            v-for="(formItemConfigList, group) in group_formItemConfigList_Obj"
            :key="group"
          >
            <template #title>
              <div class="font-bold text-14px">
                {{ group }}
              </div>
            </template>
            <S-formRow
              :formItemConfigList="formItemConfigList"
              :colNum="props.colNum"
              :action="props.action"
              v-model="localFormData"
              :disabled="props.disabled"
            >
              <template
                v-for="formItemConfig in formItemConfigList.filter(
              (item:any) => item.type === 'custom'
            )"
                :key="formItemConfig.prop"
                #[formItemConfig.prop]
              >
                <slot :name="formItemConfig.prop" />
              </template>
            </S-formRow>
          </el-collapse-item>
        </el-collapse>
        <S-formRow
          v-else
          :formItemConfigList="formItemConfigList"
          :colNum="props.colNum"
          :action="props.action"
          :disabled="props.disabled"
          v-model="localFormData"
        >
          <template
            v-for="formItemConfig in formItemConfigList.filter(
              (item:any) => item.type === 'custom'
            )"
            :key="formItemConfig.prop"
            #[formItemConfig.prop]
          >
            <slot :name="formItemConfig.prop" />
          </template>
        </S-formRow>
      </el-form>
    </el-scrollbar>
    <div class="flex justify-center p4" v-if="!props.disabled && !hideHandle">
      <el-button @click="props.cancel">取消</el-button>
      <el-button type="primary" @click="submitForm(formRef)">保存</el-button>
    </div>
    <S-msgWin :msg="callbackMessage" />
  </div>
</template>
